package multithreading;

import java.lang.reflect.Method;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @Author: 海琳琦
 * @Date: 2022/4/3 22:38
 * 创建线程方式四：使用线程池
 * 背景：经常创建、销毁使用量特别大的资源，比如并发下的线程，对性能影响很大
 * 思路：提前创建好多个线程，放入线程池中，使用时直接获取，使用完放回池中。可以避免频繁创建销毁，实现重复利用。
 * 好处：提高响应速度（减少了创建线程的时间）
 *       降低资源消耗（重复利用线程池中的线程，不需要每次都创建）
 *       便于线程管理:
 *                    corePoolSize：核心池大小
 *                    maximumPoolSize：最大线程数
 *                    keepAliveTime：线程没有任务时最多保持多长时间后会终止
 * 相关API：ExecutorService和Executors
 *
 * ExecutorService：真正的线程池接口。常见子类ThreadPoolExecutor
 *          void execute(Runnable command):执行任务/命令，没有返回值，一般用来执行Runnable
 *          <T> Future<T> submit(Callable<T> task):执行任务，有返回值，一般又来执行Callable
 *          void shutdown():关闭连接池
 *
 * Executors:工具类、线程池的工厂类，用于创建并返回不同类型的线程池
 *          Executors.newCachedThreadPool()：可缓存线程池，如果任务过多，还会继续不断创建新的线程。
 *          Executors.newFixedThreadPool(n)：固定长度的线程池，可以控制线程的最大并发数，超出的线程会放到阻塞队列中
 *          Executors.newSingleThreadExecutor()：创建一个只有一个线程的线程池
 *          Executors.newScheduledThreadPool(n)：用于定时执行任务的线程池
 *
 */
class NumberThread implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            if (i % 2 == 0) {
                System.out.println(Thread.currentThread().getName() +"："+ i);
            }
        }
    }
}

class NumberThread1 implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            if (i % 2 != 0) {
                System.out.println(Thread.currentThread().getName() +"："+ i);
            }
        }
    }
}

public class ThreadCreate3 {

    public static void main(String[] args) {
        //1、提供指定线程数量的连接池（这种方式对线程的控制粒度比较低，推荐手动创建）
        ExecutorService service = Executors.newFixedThreadPool(10);
        ThreadPoolExecutor poolExecutor = (ThreadPoolExecutor) service;
//        poolExecutor.setCorePoolSize();
        //适合Runnable
        //2、执行指定的线程操作。
        service.execute(new NumberThread());
        service.execute(new NumberThread1());
        //使用与Callable
//        service.submit();
        //3、关闭连接池
        service.shutdown();
    }
}
